home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Simulation / PDP-8 Simulator / Source Code / PDPSimWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-13  |  24.2 KB  |  961 lines  |  [TEXT/KAHL]

  1. /*************************************************************************************
  2. *
  3. *        PDP-8 Simulation Program- simulator user interface
  4. *
  5. *        ©1992 Graham Cox. All Rights Reserved.
  6. *
  7. *        Modification History:
  8. *        9/3/92 created from scratch.    
  9. *
  10. *
  11. *
  12. *************************************************************************************/
  13.  
  14. #include    "PDPGlobalEqu.p"
  15. #include    "EditGlobalEqu.p"
  16.  
  17. #include "PDPSimWindow.proto.h"
  18.  
  19. PDPMemHdl        GetMemory(WindowPtr theWindow);
  20. PDPRegHdl        GetCPU(WindowPtr theWindow);
  21. PrefsRecHdl        GetPrefs(WindowPtr theWindow);
  22. ProcessRecHdl    GetProcess(WindowPtr theWindow);
  23. ControlHandle    GetMemScrollbar(WindowPtr theWindow);
  24. textEdHdl         NewEditRecord(WindowPtr ownerWindow);
  25. textEdHdl         GetWEditRecord(WindowPtr theWindow);
  26. char            IsEditKind(WindowPtr theWindow);
  27.  
  28. extern    GrafPtr    StatBarGrafix;
  29.  
  30. GetClipRect(WindowPtr theWindow,Rect *theRect)
  31. {
  32.     /* returns rectangle of scrollable content area of window */
  33.     
  34.     Rect        r;
  35.     textEdHdl    theText;
  36.     
  37.     if (theWindow != NIL) {
  38.         r = theWindow->portRect;
  39.         r.right -= 15;
  40.         r.bottom -= 15;
  41.         if (IsSimulator(theWindow))
  42.             r.left = r.right-memAreaWidth;
  43.         else {
  44.             if (IsEditKind(theWindow)) {
  45.                 theText = GetWEditRecord(theWindow);
  46.                 r.top += GetTabBarHeight(theText) +2;    /* tab bar height */
  47.             }
  48.         }
  49.         *theRect = r;
  50.     }
  51. }
  52.  
  53.  
  54. SetWindowClip(WindowPtr theWindow)
  55. {
  56.     /* sets clip region of window to scrollable area */
  57.     
  58.     Rect        r;
  59.     GrafPtr        savePort;
  60.     
  61.     GetClipRect(theWindow,&r);
  62.     if (theWindow  != NIL) {
  63.         GetPort(&savePort);
  64.         SetPort(theWindow);
  65.         ClipRect(&r);
  66.         SetPort(savePort);
  67.     }
  68. }
  69.  
  70.  
  71. SetInverseClip(WindowPtr theWindow)
  72. {
  73.     /* sets clip region to interior minus scrollable area and scrollbars */
  74.     Rect    r;
  75.     GrafPtr    savePort;
  76.     
  77.     r = theWindow->portRect;
  78.     r.bottom -= 15;
  79.     if (IsSimulator(theWindow))
  80.         r.right -= memAreaWidth;
  81.     
  82.     GetPort(&savePort);
  83.     SetPort(theWindow);
  84.     ClipRect(&r);
  85.     SetPort(savePort);
  86. }
  87.  
  88.  
  89. UnClipWindow(WindowPtr theWindow)
  90. {
  91.     /* sets clip region to full port rect */
  92.     
  93.     GrafPtr     savePort;
  94.     Rect        r;
  95.     
  96.     if (theWindow != NIL) {
  97.         SetRect(&r,-32768,-32768,32767,32767);
  98.         GetPort(&savePort);
  99.         SetPort(theWindow);
  100.         ClipRect(&r);
  101.         SetPort(savePort);
  102.     }
  103. }
  104.  
  105.  
  106. MoveScrollbar(WindowPtr theWindow,ControlHandle vS)
  107. {
  108.     /* code stub shared by ResizeWindow and ZoomScrollWindow to move the scrollbar to
  109.         the window edge. The window should have been set to the new size & bars hidden
  110.         before calling, and theWindow must be current port */
  111.     
  112.     Rect    tempRect;
  113.     
  114.     if (theWindow!=NIL && vS!=NIL){            
  115.         tempRect=(**vS).contrlRect;
  116.         tempRect.bottom+=15;                        /* erase the grow icon */
  117.         EraseRect(&tempRect);
  118.         InvalRect(&tempRect);
  119.  
  120.         tempRect=theWindow->portRect;
  121.         /* move the bar to the window edge, resizing if necessary */
  122.  
  123.         MoveControl(vS,tempRect.right-15,tempRect.top-1);
  124.         SizeControl(vS,16,tempRect.bottom-tempRect.top-13);
  125.         
  126.         tempRect=(**vS).contrlRect;
  127.         ValidRect(&tempRect);
  128.         ShowControl(vS);
  129.         
  130.         if (IsSimulator(theWindow)) {
  131.             ResetPCMarker(theWindow);
  132.             tempRect=theWindow->portRect;
  133.             tempRect.top = tempRect.bottom-14;
  134.             tempRect.right = tempRect.left +90;
  135.             InvalRect(&tempRect);
  136.         }
  137.     }
  138. }
  139.  
  140.  
  141. ResizeWindow(WindowPtr theWindow,int width,int height)
  142. {
  143.     /* call in response to a grow or zoom request for the window- This routine moves the
  144.         scrollbars referenced by vS (vertical) and hS (horizontal), sorts out the various
  145.         update region manipulations required, and sets the clip region for the window to
  146.         exclude the scrollbars. It draws the controls as required, but removes them from
  147.         the update region to stop them being drawn twice. */
  148.         
  149.     Rect            tempRect;
  150.     GrafPtr            savePort;
  151.     ControlHandle    vS,hS;
  152.     int                vCheck;
  153.             
  154.     if (theWindow!=NIL) {
  155.         GetPort(&savePort);
  156.         SetPort(theWindow);
  157.         
  158.         if (IsSimulator(theWindow)) {
  159.             vS = GetMemScrollbar(theWindow);
  160.             
  161.             vCheck = GetCtlValue(vS);
  162.             
  163.             /* first, hide the bars and mark their areas for update */
  164.     
  165.             if (vS!=NIL)
  166.                 HideControl(vS);
  167.     
  168.             GetClipRect(theWindow,&tempRect);
  169.             EraseRect(&tempRect);
  170.             InvalRect(&tempRect);
  171.             tempRect = theWindow->portRect;
  172.             tempRect.top = tempRect.bottom-17;
  173.             EraseRect(&tempRect);
  174.             InvalRect(&tempRect);        
  175.             
  176.             SizeWindow(theWindow,width,height,TRUE);
  177.             
  178.             GetClipRect(theWindow,&tempRect);
  179.             EraseRect(&tempRect);
  180.             InvalRect(&tempRect);
  181.             
  182.             MoveScrollbar(theWindow,vS);
  183.             DrawGrowIcon(theWindow);
  184.         }
  185.         SetPort(savePort);
  186.     }
  187. }
  188.  
  189.  
  190. ZoomScrollWindow(WindowPtr theWindow,int partCode,short front)
  191. {
  192.     /* replaces ZoomWindow function when window has scrollbars */
  193.     
  194.     ControlHandle    vS;
  195.     
  196.     if (theWindow!=NIL && IsSimulator(theWindow)) {
  197.         vS = GetMemScrollbar(theWindow);
  198.         if (vS!=NIL)
  199.             HideControl(vS);
  200.             
  201.         ZoomWindow(theWindow,partCode,front);
  202.         MoveScrollbar(theWindow,vS);
  203.         DrawGrowIcon(theWindow);
  204.     }
  205. }
  206.  
  207.  
  208. DrawPDPWindow(WindowPtr theWindow)
  209. {
  210.     /* call to update the window, which must be of type simulator. Can be called from 
  211.         update event or whenever processor status changes. The window must be current
  212.         port and visRgn should be set up */
  213.         
  214.     PicHandle        diagram;
  215.     Rect            pBox;
  216.     ControlHandle    mScroll;
  217.     ProcessRecHdl    wProcess;
  218.     PDPMemHdl        procMem;
  219.     int                mHeight;
  220.     PDPRegHdl        theCPU;
  221.     PrefsRecHdl        thePrefs;
  222.     Str32            nfString;
  223.     
  224.     if (IsSimulator(theWindow)) {
  225.         wProcess = GetProcess(theWindow);
  226.         mScroll = GetMemScrollbar(theWindow);
  227.         procMem = GetMemory(theWindow);
  228.         theCPU = GetCPU(theWindow);
  229.         
  230.         diagram = GetPicture(129);
  231.         SetInverseClip(theWindow);
  232.         if (diagram != NIL) {
  233.             pBox = (*diagram)->picFrame;
  234.             AlignToZero(&pBox);
  235.             OffsetRect(&pBox,10,2+statusBarHeight);
  236.             DrawPicture(diagram,&pBox);
  237.             ReleaseResource(diagram);
  238.         }
  239.         DrawStatusBar(theWindow,theCPU);
  240.         pBox = theWindow->portRect;
  241.         MoveTo(0,statusBarHeight);
  242.         LineTo(pBox.right,statusBarHeight);
  243.         SetWindowClip(theWindow);
  244.         mHeight = (*wProcess)->memLocHeight;
  245.         
  246.         thePrefs = GetPrefs(theWindow);
  247.         DrawMemoryArea(GetCtlValue(mScroll),
  248.                         (*thePrefs)->NumberFormat,
  249.                         MemLocsInWindow(theWindow),
  250.                         procMem,
  251.                         mHeight,
  252.                         theCPU);
  253.                         
  254.         SetInverseClip(theWindow);
  255.         UpdateRegisters(theWindow);
  256.         UnClipWindow(theWindow);
  257.         pBox.top = pBox.bottom-12;
  258.         pBox.right = pBox.left + 90;
  259.         OffsetRect(&pBox,5,-2);
  260.         GetIndString(&nfString,128,(*thePrefs)->NumberFormat+3);
  261.         TextFont(geneva);
  262.         TextSize(9);
  263.         TextBox(&nfString[1],nfString[0],&pBox,teJustLeft);
  264.         TextFont(0);
  265.         TextSize(12);
  266.     }
  267. }
  268.  
  269.  
  270. DrawMemoryArea(PDPWord topAddress,
  271.                 int NumFormat,
  272.                 int nCells,
  273.                 PDPMemHdl procMem,
  274.                 int mHeight,
  275.                 PDPRegHdl theCPU)
  276. {
  277.     /* draws the memory area in the current window. Clipping and port must be set up */
  278.     
  279.     PDPMemPtr    addrPtr;
  280.     PDPWord        data,i;
  281.     Str32        vText;
  282.     Rect        tBox;
  283.     int            dH;
  284.     
  285.     if (procMem != NIL) {
  286.         MoveTo(thePort->portRect.right-memAreaWidth,thePort->portRect.top);
  287.         LineTo(thePort->portRect.right-memAreaWidth,thePort->portRect.bottom-15);
  288.         dH = memAreaWidth/2-14;
  289.         SetRect(&tBox,0,0,dH,mHeight);
  290.         OffsetRect(&tBox,thePort->portRect.right-(memAreaWidth-14),0);
  291.         
  292.         HLock((Handle) procMem);
  293.         
  294.         for(i=topAddress;i < topAddress + nCells;i++) {
  295.             addrPtr = *procMem;
  296.             if (i<4096) {
  297.                 data = *(addrPtr + i);
  298.                 GetNumberString((long)i,NumFormat,&vText);
  299.                 TextBox(&vText[1],vText[0],&tBox,teJustLeft);
  300.                 InsetRect(&tBox,-1,-1);
  301.                 FrameRect(&tBox);
  302.                 InsetRect(&tBox,1,1);
  303.                 OffsetRect(&tBox,dH,0);
  304.                 GetNumberString((long)data,NumFormat,&vText);
  305.                 TextBox(&vText[1],vText[0],&tBox,teJustLeft);
  306.                 InsetRect(&tBox,-1,-1);
  307.                 FrameRect(&tBox);
  308.                 InsetRect(&tBox,1,1);
  309.                 OffsetRect(&tBox,-dH,mHeight);
  310.             }
  311.         }
  312.         HUnlock((Handle) procMem);
  313.         PlotPCMarker(theCPU,mHeight,topAddress);
  314.     }
  315. }
  316.  
  317.  
  318. RefreshSimWindow(WindowPtr theWindow)
  319. {
  320.     /* draws the given sim window */
  321.     
  322.     GrafPtr            savePort;
  323.     ProcessRecHdl    theProcess;
  324.     
  325.     GetPort(&savePort);
  326.     SetPort(theWindow);
  327.     SetWindowClip(theWindow);
  328.     theProcess = GetProcess(theWindow);
  329.     if (theProcess != NIL)
  330.         PlotPCMarker(GetCPU(theWindow),
  331.                     (*theProcess)->memLocHeight,
  332.                     GetCtlValue((*theProcess)->memScroll));
  333.                 
  334.     SetInverseClip(theWindow);
  335.     UpdateRegisters(theWindow);
  336.     UnClipWindow(theWindow);
  337.     SetPort(savePort);
  338. }
  339.  
  340.  
  341. UpdateRegisters(WindowPtr theWindow)
  342. {
  343.     /* redraws the register values in the current process window */
  344.     
  345.     Rect        tBox;
  346.     PDPRegHdl    theCPU;
  347.     Str32        vText;
  348.     int            numBase;
  349.     PrefsRecHdl    thePrefs;
  350.     
  351.     SetRect(&tBox,0,0,80,18);
  352.     OffsetRect(&tBox,240,22+statusBarHeight);
  353.     
  354.     theCPU = GetCPU(theWindow);
  355.     thePrefs = GetPrefs(theWindow);
  356.     numBase = (*thePrefs)->NumberFormat;
  357.     if (theCPU != NIL) {
  358.         GetNumberString((long)(*theCPU)->PC,numBase,&vText);
  359.         TextBox(&vText[1],vText[0],&tBox,teJustRight);
  360.         
  361.         OffsetRect(&tBox,0,51);
  362.         GetNumberString((long)(*theCPU)->EAR,numBase,&vText);
  363.         TextBox(&vText[1],vText[0],&tBox,teJustRight);
  364.         
  365.         OffsetRect(&tBox,0,51);
  366.         GetNumberString((long)(*theCPU)->IR,numBase,&vText);
  367.         TextBox(&vText[1],vText[0],&tBox,teJustRight);
  368.         
  369.         AlignToZero(&tBox);
  370.         OffsetRect(&tBox,47,124+statusBarHeight);
  371.         GetNumberString((long)(*theCPU)->ACC,numBase,&vText);
  372.         TextBox(&vText[1],vText[0],&tBox,teJustRight);
  373.         
  374.         OffsetRect(&tBox,99,0);
  375.         InsetRect(&tBox,32,0);
  376.         GetNumberString((long)((*theCPU)->CCR & Link),numBase,&vText);
  377.         TextBox(&vText[1],vText[0],&tBox,teJustCenter);
  378.         
  379.     }
  380. }
  381.  
  382.  
  383. GetNumberString(long theNumber,int numBase,Str32 *theString)
  384. {
  385.     /* returns the string representing the number in decimal, octal or hex */
  386.     
  387.     if (numBase == Decimal)
  388.         NumToString(theNumber,theString);
  389.     else
  390.         if (numBase == Octal)
  391.             NumToOctal(theNumber,theString);
  392.         else
  393.             NumToHexx(theNumber,theString);
  394. }
  395.  
  396.  
  397. DrawStatusBar(WindowPtr theWindow,PDPRegHdl theCPU)
  398. {
  399.     /* draws the status bar in the window. This is a copyBits from an offscreen port,
  400.         which is done to allow the buttons to be drawn in various states easily. The
  401.         window MUST be the current port, and clipping set up already */
  402.     
  403.     Rect    src,dest;
  404.     int        CPUStatus;
  405.     
  406.     if (theWindow != NIL && theCPU != NIL) {
  407.         CPUStatus = (*theCPU)->CCR;
  408.         SetRect(&src,0,0,StatBarGrafix->portRect.right,statusBarHeight);
  409.         dest = src;
  410.         CopyBits(&StatBarGrafix->portBits,&theWindow->portBits,&src,&dest,srcCopy,NIL);
  411.         SetRect(&src,0,0,70,20);
  412.         dest = src;
  413.         OffsetRect(&src,10,30);
  414.         OffsetRect(&dest,10,0);
  415.         if (CPUStatus & HaltBit) {
  416.             OffsetRect(&src,80,0);
  417.             OffsetRect(&dest,80,0);
  418.         }
  419.         CopyBits(&StatBarGrafix->portBits,&theWindow->portBits,&src,&dest,srcCopy,NIL);
  420.     }
  421. }
  422.  
  423.  
  424. GrafPtr MakeAPort(int pictID,int pixDepth)
  425. {
  426.     /* given a PICT resource ID, this routine creates an offscreen port of the depth
  427.         specified, draws the picture into it, and returns it's pointer. The depth can be
  428.         8 bits or 1 bit, or if 0 is passed, the depth of the main screen is used. */
  429.         
  430.     OSErr            theErr;
  431.     PicHandle        thePicture;
  432.     GrafPtr            thePicPort,savePort;
  433.     Rect            picRect;
  434.     int                width,height;
  435.     long            storage,rowB;
  436.     PixMapHandle    colourPix;
  437.     Handle            RAMChunk;
  438.     GDHandle        maxDev,saveDev;
  439.     
  440.     thePicture=GetPicture(pictID);                            /* fetch the picture to draw */
  441.     if (thePicture!=NIL && (pixDepth==1 || pixDepth==8 || pixDepth==0)) {
  442.         
  443.         if (!IsInColour())
  444.             pixDepth=1;                                        /* force 1 bit graphics on B & W mac */
  445.         else {
  446.             if (pixDepth==0) {
  447.                 maxDev=GetMainDevice();
  448.                 if (maxDev!=NIL) {
  449.                     colourPix=(**maxDev).gdPMap;
  450.                     pixDepth=(**colourPix).pixelSize;        /* determine depth of screen */
  451.                 }
  452.             }
  453.         }
  454.         picRect=(**thePicture).picFrame;                    /* get size of picture     */
  455.         OffsetRect(&picRect,-picRect.left,-picRect.top);    /* align to zero         */
  456.         thePicPort=(GrafPtr)NewPtr(sizeof(GrafPort));        /* get new port         */ 
  457.         if (thePicPort!=NIL) {
  458.             GetPort(&savePort);
  459.  
  460.             if (pixDepth==1)
  461.                 OpenPort(thePicPort);                        /* initialise port as B & W */
  462.             else
  463.                 OpenCPort(thePicPort);                        /* initialise port as Colour */
  464.  
  465.             width=picRect.right-picRect.left;
  466.             height=picRect.bottom-picRect.top;
  467.             thePicPort->portRect=picRect;
  468.             RectRgn(thePicPort->visRgn,&picRect);            /* set port regions to equal portrect */
  469.             RectRgn(thePicPort->clipRgn,&picRect);
  470.             rowB=((width * pixDepth)+15)/16 * 2;            /* determine row offset */
  471.             storage=(long)height * rowB;                    /* determine size of bit image for port */
  472.             RAMChunk=NewHandle(storage);                    /* get a lump of memory to hold image */
  473.             if (RAMChunk!=NIL) {
  474.                 MoveHHi(RAMChunk);                            /* move it out of the way */
  475.                 HLock(RAMChunk);                            /* lock it (accessed via pointer) */
  476.                 if (pixDepth==1) {
  477.                     /* set up bitmap for B & W port */
  478.                     
  479.                     thePicPort->portBits.bounds=picRect;
  480.                     thePicPort->portBits.rowBytes=BitAnd(rowB,0xFFFF);
  481.                     thePicPort->portBits.baseAddr=*RAMChunk;
  482.                 }
  483.                 else {
  484.                     /* set up pixmap for colour port */
  485.                     
  486.                     colourPix=(*(CGrafPtr)thePicPort).portPixMap;
  487.                     if (colourPix!=NIL) {
  488.                         (**colourPix).bounds=picRect;
  489.                         (**colourPix).rowBytes=BitOr(rowB,0x8000);
  490.                         (**colourPix).baseAddr=*RAMChunk;
  491.                         (**colourPix).pixelSize=pixDepth;
  492.                     }
  493.                 }
  494.                 SetPort(thePicPort);                /* set current port to our new one */
  495.                 ForeColor(blackColor);
  496.                 BackColor(whiteColor);
  497.                 EraseRect(&thePicPort->portRect);    /* clear port */
  498.                 thePicture=GetPicture(pictID);        /* get picture again (it maybe got purged)*/ 
  499.                 DrawPicture(thePicture,&picRect);    /* draw picture into offscreen image */
  500.                 ReleaseResource(thePicture);        /* let picture go */
  501.                 SetPort(savePort);
  502.                 return(thePicPort);
  503.             }
  504.             else {
  505.                 if (pixDepth==1)
  506.                     ClosePort(thePicPort);
  507.                 else
  508.                     CloseCPort(thePicPort);
  509.                 DisposPtr(thePicPort);
  510.             }
  511.         }                
  512.     }
  513.     SysBeep(1);        
  514.     return(NIL);                    
  515. }
  516.  
  517.  
  518. CloseAPort(GrafPtr theOSPort)
  519. {
  520.     /* disposes of off-screen port */
  521.  
  522.     Handle            theImage;
  523.     PixMapHandle    colourPix;    
  524.     char            portIsColour;
  525.     
  526.     if (theOSPort!=NIL){
  527.         portIsColour=((theOSPort->portBits.rowBytes & 0xC000)!=0);    /* find out if port is colour */
  528.         if (portIsColour) {
  529.             colourPix=(*(CGrafPtr)theOSPort).portPixMap;
  530.             theImage=RecoverHandle((**colourPix).baseAddr);            /* find long-lost handle */
  531.         }
  532.         else
  533.             theImage=RecoverHandle(theOSPort->portBits.baseAddr);
  534.         
  535.         if (theImage!=NIL) {
  536.             HUnlock(theImage);                                        /* free that locked block! */
  537.             DisposHandle(theImage);                                    /* dispose of image in memory */
  538.         }
  539.         if (portIsColour)
  540.             CloseCPort(theOSPort);
  541.         else
  542.             ClosePort(theOSPort);                                    /* dispose of port's storage */
  543.  
  544.         DisposPtr(theOSPort);                                        /* get rid of the port itself */
  545.     }
  546. }
  547.  
  548.  
  549. int    IsInColour(void)
  550. {
  551.     /* returns TRUE if a colour Mac with a colour main monitor, else FALSE */
  552.     
  553.     SysEnvRec        macEnv;
  554.     GDHandle        macGDevice;
  555.     OSErr            theErr;
  556.     PixMapHandle    macScreen;
  557.     
  558.     theErr = SysEnvirons(2,&macEnv);
  559.     if (!theErr) {
  560.         if (macEnv.hasColorQD) {
  561.             macGDevice = GetMainDevice();
  562.             if (macGDevice != NIL) {
  563.                 macScreen = (*macGDevice)->gdPMap;
  564.                 if (macScreen != NIL) {
  565.                     if ((*macScreen)->pixelSize > 2)
  566.                         return(TRUE);
  567.                 }
  568.             }
  569.         }
  570.     }
  571.     return(FALSE);
  572. }
  573.  
  574.  
  575. int        MemLocsInWindow(WindowPtr theWindow)
  576. {
  577.     /* returns the number of memory locations that can be displayed in the window. This
  578.         is just the memLocHeight divided into the window height. */
  579.     
  580.     ProcessRecHdl    theProcess;
  581.     Rect            wRect;
  582.         
  583.     if (IsSimulator(theWindow)) {
  584.         theProcess = GetProcess(theWindow);
  585.         GetClipRect(theWindow,&wRect);
  586.         return((wRect.bottom-wRect.top)/(*theProcess)->memLocHeight +1);
  587.     }
  588. }
  589.  
  590.  
  591. PlotPCMarker(PDPRegHdl theCPU,int mLocHeight,PDPWord topAddress)
  592. {
  593.     /* draws the PC marker arrow pointing to the current address. topAddress is the
  594.         address of the location at the top of the window, and mLocHeight is the height
  595.         in pixels of each location box. Current port must be set up with any clipping */
  596.         
  597.     Rect    src,dest;
  598.     PDPWord    cAddr,bottomAddr;
  599.     
  600.     if (theCPU != NIL) {
  601.         EraseRect(&(*theCPU)->markerLoc);
  602.         cAddr = (*theCPU)->PC;
  603.         if (cAddr >= topAddress && cAddr <= (topAddress + MemLocsInWindow(thePort))) {
  604.             SetRect(&src,0,0,10,10);
  605.             dest = src;
  606.             OffsetRect(&src,370,38);
  607.             OffsetRect(&dest,
  608.                         thePort->portRect.right-(memAreaWidth-2),
  609.                         (cAddr - topAddress) * mLocHeight + 5);
  610.                         
  611.             CopyBits(&StatBarGrafix->portBits,&thePort->portBits,&src,&dest,srcCopy,NIL);
  612.             (*theCPU)->markerLoc = dest;
  613.         }
  614.     }
  615. }
  616.  
  617.  
  618. ResetPCMarker(WindowPtr theWindow)
  619. {
  620.     /* for a sim window, sets the marker rectangle to empty- required when a window is resized */
  621.     
  622.     PDPRegHdl        theCPU;
  623.     
  624.     theCPU = GetCPU(theWindow);
  625.     if (theCPU != NIL) 
  626.         SetRect(&(*theCPU)->markerLoc,0,0,0,0);
  627. }
  628.  
  629.  
  630. pascal void MemScrollProc(ControlHandle theControl,int partCode)
  631. {
  632.     /* action procedure to scroll the memory display in the window */
  633.     
  634.     Rect            mArea;
  635.     RgnHandle        updateRgn;
  636.     WindowPtr        target;
  637.     ProcessRecHdl    theProcess;
  638.     PrefsRecHdl        thePrefs;
  639.     int                pScrollDist,pageAmt,ctlChange;
  640.     
  641.     target = (*theControl)->contrlOwner;
  642.     GetClipRect(target,&mArea);
  643.     mArea.left +=15;
  644.     theProcess = GetProcess(target);
  645.     if (theProcess != NIL) {
  646.         pageAmt = MemLocsInWindow(target)-2;
  647.         ctlChange = GetCtlValue(theControl);
  648.         
  649.         switch (partCode) {
  650.             case inUpButton:
  651.                 SetCtlValue(theControl,GetCtlValue(theControl)-1);
  652.                 break;
  653.             case inDownButton:
  654.                 SetCtlValue(theControl,GetCtlValue(theControl)+1);
  655.                 break;
  656.             case inPageUp:
  657.                 SetCtlValue(theControl,GetCtlValue(theControl)-pageAmt);
  658.                 break;
  659.             case inPageDown:
  660.                 SetCtlValue(theControl,GetCtlValue(theControl)+pageAmt);
  661.                 break;
  662.         }
  663.         
  664.         ctlChange = ctlChange - GetCtlValue(theControl);
  665.         pScrollDist = (*theProcess)->memLocHeight * ctlChange;
  666.         
  667.         updateRgn = NewRgn();
  668.         
  669.         ScrollRect(&mArea,0,pScrollDist,updateRgn);
  670.         InvalRgn(updateRgn);
  671.         BeginUpdate(target);
  672.         thePrefs = GetPrefs(target);
  673.         DrawMemoryArea(GetCtlValue(theControl),
  674.                         (*thePrefs)->NumberFormat,
  675.                         pageAmt+2,
  676.                         GetMemory(target),
  677.                         (*theProcess)->memLocHeight,
  678.                         GetCPU(target));
  679.                         
  680.         EndUpdate(target);
  681.         DisposeRgn(updateRgn);
  682.     }
  683. }
  684.  
  685.  
  686. ClickSimWindow(WindowPtr theWindow,Point clickPt)
  687. {
  688.     /* handles clicks for a sim window. Window is current port, and already verified
  689.         as a sim window. ClickPt is in local coordinates */
  690.         
  691.     ControlHandle    mBar;
  692.     int                partCode;
  693.     Rect            mRect,pRect;
  694.     PrefsRecHdl        thePrefs;
  695.     
  696.     partCode = FindControl(clickPt,theWindow,&mBar);
  697.     if (partCode == inThumb) {
  698.         partCode = TrackControl(mBar,clickPt,NIL);
  699.         if (partCode != 0) {
  700.             GetClipRect(theWindow,&mRect);
  701.             if (GetCtlValue(mBar) > 4096-MemLocsInWindow(theWindow))
  702.                 EraseRect(&mRect);
  703.             InvalRect(&mRect);
  704.         }
  705.     }
  706.     else {
  707.         if (partCode != 0)
  708.             partCode = TrackControl(mBar,clickPt,&MemScrollProc);
  709.         else {
  710.             /* we did not click a control, so hit test other parts of the window */
  711.             pRect = theWindow->portRect;
  712.             SetRect(&mRect,0,0,pRect.right-memAreaWidth,statusBarHeight);
  713.             if (PtInRect(clickPt,&mRect))
  714.                 StatBarHit(theWindow,clickPt);
  715.             else {
  716.                 GetClipRect(theWindow,&mRect);
  717.                 mRect.left += memAreaWidth/2 +14;
  718.                 if (PtInRect(clickPt,&mRect)) {
  719.                     thePrefs = GetPrefs(theWindow);
  720.                     EditMemLocation(theWindow,clickPt,(*thePrefs)->NumberFormat);
  721.                 }
  722.                 else {
  723.                     GetClipRect(theWindow,&mRect);
  724.                     mRect.left+= 14;
  725.                     mRect.right = mRect.left + 14;
  726.                     if (PtInRect(clickPt,&mRect))
  727.                         SetPCToClick(GetCPU(theWindow),GetProcess(theWindow),clickPt);
  728.                 }
  729.             }
  730.         }
  731.     }
  732. }
  733.  
  734.  
  735. StatBarHit(WindowPtr theWindow,Point clickPt)
  736. {
  737.     /* hit tests buttons in the stat bar, tracking and performing action accordingly */
  738.     
  739.     Rect    buttonRect,src,dest;
  740.     int        index;
  741.     long    dTime;
  742.     
  743.     SetRect(&buttonRect,0,0,70,20);
  744.     OffsetRect(&buttonRect,10,0);
  745.     for (index =0;index<4;index++) {
  746.         if (PtInRect(clickPt,&buttonRect))
  747.             break;
  748.         OffsetRect(&buttonRect,85,0);
  749.     }
  750.     if (index >=4)
  751.         return(0);
  752.     
  753.     SetInverseClip(theWindow);
  754.         
  755.     src = buttonRect;
  756.     OffsetRect(&src,0,30);
  757.     CopyBits(&StatBarGrafix->portBits,&theWindow->portBits,&src,&buttonRect,srcCopy,NIL);
  758.     OffsetRect(&src,0,-30);
  759.     
  760.     switch (index) {
  761.         case 0:
  762.             ResumePDP(theWindow);
  763.             break;
  764.         case 1:
  765.             StopPDP(theWindow);
  766.             break;
  767.         case 2:
  768.             Delay(10,&dTime);
  769.             ResetPDP(theWindow);
  770.             SetInverseClip(theWindow);
  771.             CopyBits(&StatBarGrafix->portBits,&theWindow->portBits,&src,&buttonRect,srcCopy,NIL);
  772.             break;
  773.         case 3:
  774.             Delay(10,&dTime);
  775.             StepPDP(theWindow);
  776.             SetInverseClip(theWindow);
  777.             CopyBits(&StatBarGrafix->portBits,&theWindow->portBits,&src,&buttonRect,srcCopy,NIL);
  778.             break;
  779.     }
  780.     UnClipWindow(theWindow);
  781. }
  782.  
  783.  
  784. UpdateMemoryLocation(WindowPtr theWindow)
  785. {
  786.     /* called when the process requests a memory update. If the affected location is 
  787.         visible in the window, that location is identified, clipped to, and the memory
  788.         draw procedure is called. The cpu's EAR points to the location */
  789.     
  790.     GrafPtr            savePort;
  791.     PDPRegHdl        theCPU;
  792.     PDPWord            topAddress,refreshAddr;
  793.     PDPMemPtr        targLocation;
  794.     PrefsRecHdl        thePrefs;
  795.     Rect            locRect;
  796.     ProcessRecHdl    theProcess;
  797.     long            dTime;
  798.     
  799.     if (IsSimulator(theWindow)) {
  800.         topAddress = GetCtlValue(GetMemScrollbar(theWindow));
  801.         theCPU = GetCPU(theWindow);
  802.         refreshAddr = (*theCPU)->EAR;
  803.         if (refreshAddr >= topAddress &&
  804.             refreshAddr <= topAddress + MemLocsInWindow(theWindow)) {
  805.             thePrefs = GetPrefs(theWindow);
  806.             theProcess = GetProcess(theWindow);
  807.             GetPort(&savePort);
  808.             SetPort(theWindow);
  809.             
  810.             SetRect(&locRect,0,0,memAreaWidth/2-15,(*theProcess)->memLocHeight-3);
  811.             OffsetRect(&locRect,theWindow->portRect.right-memAreaWidth/2,
  812.                             (refreshAddr - topAddress) * (*theProcess)->memLocHeight);
  813.             InsetRect(&locRect,2,1);                
  814.             ClipRect(&locRect);
  815.             DrawMemoryArea(topAddress,
  816.                             (*thePrefs)->NumberFormat,
  817.                             MemLocsInWindow(theWindow),
  818.                             GetMemory(theWindow),
  819.                             (*theProcess)->memLocHeight,
  820.                             theCPU);
  821.             UnClipWindow(theWindow);
  822.             SetPort(savePort);
  823.         }
  824.     }
  825. }
  826.  
  827. #define    EditMemLocDialogID    514
  828.         
  829.  
  830. EditMemLocation(WindowPtr theWindow,Point clickPt,int nFormat)
  831. {
  832.     /* selects a memory cell for editing. Window must be current port & verified correct
  833.         type */
  834.     
  835.     PDPWord            topAddress,editAddress;
  836.     ProcessRecHdl    theProcess;
  837.     Rect            locRect,itemBox;
  838.     long            dTime,editData;
  839.     DialogPtr        theDialog;
  840.     int                theItem,itemType;
  841.     Handle            itemHand;
  842.     PDPMemHdl        theMemory;
  843.     Point            dialogOffset;
  844.     Str32            aText;
  845.     
  846.     topAddress = GetCtlValue(GetMemScrollbar(theWindow));
  847.     theProcess = GetProcess(theWindow);
  848.     editAddress = topAddress + (clickPt.v / (*theProcess)->memLocHeight);
  849.  
  850.     if (editAddress >=0 && editAddress <4096) {
  851.         SetRect(&locRect,0,0,memAreaWidth/2-15,(*theProcess)->memLocHeight-1);
  852.         OffsetRect(&locRect,theWindow->portRect.right- memAreaWidth/2,
  853.                         (editAddress - topAddress) * (*theProcess)->memLocHeight);
  854.         
  855.         SetWindowClip(theWindow);                        
  856.         InvertRect(&locRect);
  857.         Delay(8,&dTime);
  858.         InvertRect(&locRect);
  859.         UnClipWindow(theWindow);
  860.         
  861.         dialogOffset.h = locRect.left -46;
  862.         dialogOffset.v = locRect.top -3;
  863.         LocalToGlobal(&dialogOffset);
  864.         
  865.         theMemory = GetMemory(theWindow);
  866.         editData = *(*theMemory + editAddress);
  867.         switch(nFormat) {
  868.             case Decimal:
  869.                 NumToString(editData,&aText);
  870.                 break;
  871.             case Octal:
  872.                 NumToOctal(editData,&aText);
  873.                 break;
  874.             case Hexadecimal:
  875.                 NumToHexx(editData,&aText);
  876.                 break;
  877.         }
  878.         
  879.         
  880.         theDialog = GetNewDialog(EditMemLocDialogID,NIL,(WindowPtr)-1L);
  881.         if (theDialog != NIL) {
  882.             MoveWindow(theDialog,dialogOffset.h,dialogOffset.v,TRUE);
  883.             ShowWindow(theDialog);
  884.             GetDItem(theDialog,2,&itemType,&itemHand,&itemBox);
  885.             SetIText(itemHand,&aText);
  886.             SelIText(theDialog,2,0,32767);
  887.             
  888.             ModalDialog(NIL,&theItem);
  889.             
  890.             GetIText(itemHand,&aText);
  891.             DisposDialog(theDialog);
  892.             
  893.             switch (nFormat) {
  894.                 case Decimal:
  895.                     StringToNum(&aText,&editData);
  896.                     break;
  897.                 case Octal:
  898.                     OctStringToNum(&aText,&editData);
  899.                     break;
  900.                 case Hexadecimal:
  901.                     HexStringToNum(&aText,&editData);
  902.                     break;
  903.             }
  904.             *(*theMemory + editAddress) = (LoWord(editData) & 0x0FFF);
  905.         }
  906.     }
  907.     else
  908.         SysBeep(1);
  909. }
  910.  
  911.  
  912. SetPCToClick(PDPRegHdl theCPU,ProcessRecHdl theProcess,Point mClick)
  913. {
  914.     /* when mouse clicked in marker bar, address of click calculated and copied to the
  915.         program counter, then the marker is replotted. thePort must be current window */
  916.         
  917.     PDPWord        topAddress,ckAddress;
  918.     Rect        pcRect;
  919.     
  920.     if ((*theCPU)->CCR & HaltBit) {
  921.         topAddress = GetCtlValue((*theProcess)->memScroll);
  922.         ckAddress = topAddress + mClick.v / (*theProcess)->memLocHeight;
  923.         if (ckAddress >=0 && ckAddress <4096) {
  924.             (*theCPU)->PC = ckAddress;
  925.             SetWindowClip(thePort);
  926.             PlotPCMarker(theCPU,(*theProcess)->memLocHeight,topAddress);
  927.             SetRect(&pcRect,0,0,80,18);
  928.             OffsetRect(&pcRect,240,22+statusBarHeight);
  929.             InvalRect(&pcRect);
  930.             UnClipWindow(thePort);
  931.         }
  932.         else
  933.             SysBeep(1);
  934.     }
  935.     else
  936.         SysBeep(1);
  937. }
  938.  
  939.  
  940. ScrollToPC(WindowPtr theWindow)
  941. {
  942.     /* changes memory view so that current PC is first location shown */
  943.     
  944.     Rect            mView;
  945.     GrafPtr            savePort;
  946.     ControlHandle    mScroll;
  947.     PDPRegHdl        theCPU;
  948.     
  949.     if (IsSimulator(theWindow)) {
  950.         GetClipRect(theWindow,&mView);
  951.         mScroll = GetMemScrollbar(theWindow);
  952.         theCPU = GetCPU(theWindow);
  953.         if (mScroll != NIL && theCPU != NIL)
  954.             SetCtlValue(mScroll,(*theCPU)->PC);
  955.             
  956.         GetPort(&savePort);
  957.         SetPort(theWindow);
  958.         InvalRect(&mView);
  959.         SetPort(savePort);
  960.     }
  961. }